package ig.metrica.ui;

//import ig.metrica.Modelo;
//import ig.metrica.ModeloHome;
//import ig.metrica.ModeloPK;
import ig.finanzas.ManejadorBandas;
import ig.metrica.ejb.bean.Escenarios;
import ig.metrica.escenario.GeneraEscenario;
import ig.metrica.escenario.GeneraEscenarioHome;
import ig.metrica.origenesdedatos.Conexion;
import ig.metrica.origenesdedatos.ConexionHome;
import ig.metrica.origenesdedatos.OrigenDeDatos;
import ig.metrica.origenesdedatos.OrigenDeDatosHome;
import ig.metrica.origenesdedatos.OrigenDeDatosPK;
import ig.metrica.origenesdedatos.OrigenesdatosDTO;
//import ig.metrica.riesgo.MatrizCorrelacion;
//import ig.metrica.riesgo.MatrizCorrelacionHome;
import ig.util.ejb.IGLlaveInt;
import ig.util.excepciones.LogicaExcepcion;

import java.io.FileInputStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.ArrayList;
import javax.ejb.CreateException;

import javax.ejb.FinderException;
import javax.swing.JOptionPane;


import java.net.URL;
import java.util.Properties;

import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.sql.DataSource;
//import javax.mail.Session;
import javax.naming.Context;
//import org.apache.log4j.Logger;

public class ServiceLocator {
//    private static Logger log = Logger.getLogger(PrincipalMetrica.class.getName());
    private static ServiceLocator instancia = null;
    private final String INITIAL_CONTEXT_FACTORY = "org.jnp.interfaces.NamingContextFactory";
    private String host ="-";
    private String pto = "-";
    
    
    {
        String FICHERO_CONFIGURACION = "server/configuracion.properties";
        Properties propiedades;
        try {
            FileInputStream f = new FileInputStream(FICHERO_CONFIGURACION);
            propiedades = new Properties();
            propiedades.load(f);            
            f.close();
            host = propiedades.getProperty("host");
            pto = propiedades.getProperty("puerto");
            System.out.println("Server "+host+":"+pto);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null,"Problemas con el Archivo de Configuracion del Servidor "+"Error: \n"+e+"\nConsulte con el Administrador del Sistema");
        }
    }
    
    private final String url=host+":"+pto;
    private Properties prop;
    private InitialContext ctx;
    
    public static ServiceLocator getInstancia(){
        if (instancia==null){
            return instancia = new ServiceLocator();
        }else{
            return instancia;
        }
    }
    
    public ServiceLocator(){
        prop = new Properties();
        prop.put( Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        prop.put( Context.PROVIDER_URL, url);
        try {
            ctx = new InitialContext(prop);
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
    }
    
//        public ServiceLocator(Object obj) {
//            try {
//                Properties prop = new Properties();
//                prop.put( Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
//                prop.put( Context.PROVIDER_URL, Sockec);
//                ctx = new InitialContext(prop);
//            } catch (NamingException ne) {
//                throw new RuntimeException(ne);
//            }
//        }
    private ConexionHome conexionHome=null;
    public ArrayList getListaDeConexiones(String nombre, String driver, String url, String usuario, String password) throws NamingException, RemoteException, FinderException{
        if(conexionHome==null) {
            ctx = new InitialContext(prop);
            conexionHome = (ConexionHome)ctx.lookup("ig.metrica.origenesdedatos.Conexion");
        }
        Collection resultado = conexionHome.findByPropiedades( nombre, driver, url, usuario, password);
        
        ArrayList lista = new ArrayList();
        Iterator i = resultado.iterator();
        while (i.hasNext()){
            Conexion conexion = (Conexion)i.next();
            lista.add( new String( conexion.getNombre() + "("+ (IGLlaveInt)conexion.getPrimaryKey() +")" ) );
        }
        return lista;
    }
    
    public Collection getConexiones() throws NamingException, RemoteException, FinderException{
        if(conexionHome==null) {
            ctx = new InitialContext(prop);
            conexionHome = (ConexionHome)ctx.lookup("ig.metrica.origenesdedatos.Conexion");
        }
        Collection resultado = conexionHome.findByPropiedades( "","","","","");
        return resultado;
//		ArrayList lista = new ArrayList();
//		Iterator i = resultado.iterator();
//		while (i.hasNext()){
//			Conexion conexion = (Conexion)i.next();
//			lista.add( new String( conexion.getNombre() + "("+ (IGLlaveInt)conexion.getPrimaryKey() +")" ) );
//		}
//		return lista;
    }
    private GeneraEscenarioHome generaEscenarioHome=null;
    public Escenarios getEscenario()throws NamingException, RemoteException, FinderException{
        try {
            if(generaEscenarioHome==null) {
                ctx = new InitialContext(prop);
                generaEscenarioHome= (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
            }
            GeneraEscenario escenario = generaEscenarioHome.create();
            return escenario.getEscenario();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public Escenarios getEscenario(Date fecha,String modelo)throws NamingException, RemoteException, FinderException{
        try {
            if(generaEscenarioHome==null) {
                ctx = new InitialContext(prop);
                generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
            }
            GeneraEscenario escenario = generaEscenarioHome.create();
            return escenario.getEscenario(fecha,modelo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public Integer getEscenario(String modelo,String nombre)throws NamingException, RemoteException, FinderException{
        try {
            if(generaEscenarioHome==null) {
                ctx = new InitialContext(prop);
                generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
            }
            GeneraEscenario escenario = generaEscenarioHome.create();
            return escenario.getEscenario(modelo,nombre);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public void _crearEscenario(Date fecha,String modelo)throws NamingException, RemoteException, FinderException{
        try {
            if(generaEscenarioHome==null) {
                ctx = new InitialContext(prop);
                generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
            }
            GeneraEscenario escenario = generaEscenarioHome.create();
            escenario.crearEscenario(fecha,modelo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void grabarEscenario(Escenarios escenarios,String tabla,boolean finalizar)throws NamingException, RemoteException, FinderException, LogicaExcepcion, CreateException, Exception{
        ctx = new InitialContext(prop);
        generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
        GeneraEscenario escenario = generaEscenarioHome.create();
        escenario.grabarEscenario(escenarios,tabla,finalizar);
    }
    
    public String GenerarEscenario(Date fecha,String modelo,boolean debug,boolean datosActuales,ManejadorBandas bandasLiquidez, ManejadorBandas bandasRiesgo)throws NamingException, RemoteException, FinderException{
        try {
            if(generaEscenarioHome==null) {
                ctx = new InitialContext(prop);
                generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
            }
            GeneraEscenario escenario = generaEscenarioHome.create();
            return escenario.procesarEscenario(fecha,modelo,debug,datosActuales,bandasLiquidez,bandasRiesgo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public String GenerarEscenario(Date fecha,String modelo,String nombreEscenario,GeneraEscenario escenario,boolean debug,boolean datosActuales,ManejadorBandas bandasLiquidez, ManejadorBandas bandasRiesgo)throws NamingException, RemoteException, FinderException{
        try {
            if(escenario ==null){
                ctx = new InitialContext(prop);
                GeneraEscenarioHome home = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
                escenario = home.create();
            }
            return escenario.procesarEscenario(fecha,modelo,nombreEscenario,debug,datosActuales,bandasLiquidez, bandasRiesgo);
        } catch (Exception e) {
            e.printStackTrace();
            throw new FinderException(e.toString());
        }
    }
    private GeneraEscenario generaEscenario =null;
    public String getDirectorioHTML(Date fecha,String modelo)throws NamingException, RemoteException, FinderException{
        try {
            ctx = new InitialContext(prop);
            generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
            generaEscenario  = generaEscenarioHome.create();
            return generaEscenario.getDirHTML(fecha,modelo);
        } catch (Exception e) {
            e.printStackTrace();
            throw new FinderException(e.toString());
        }
    }
    
    public GeneraEscenario getGeneraEscenario() {
        return generaEscenario;
    }
    public void  setNullGeneraEscenario() {
        generaEscenario=null;
    }
    
    GeneraEscenario escenario =null;
    public GeneraEscenario pararProceso()throws NamingException, RemoteException, FinderException, LogicaExcepcion, Exception{
        try {
            if(generaEscenarioHome==null || escenario ==null) {
                ctx = new InitialContext(prop);
                generaEscenarioHome = (GeneraEscenarioHome)ctx.lookup("ig.metrica.escenario.GeneraEscenario");
                escenario = generaEscenarioHome .create();
            }
            return escenario;
        } catch (Exception e) {
            throw e;
        }
    }
//    private ModeloHome modeloHome =null;
//    public Collection getListaDeModelos() throws NamingException, RemoteException, FinderException{
//        ctx = new InitialContext(prop);
//
//        if(modeloHome==null){
//            modeloHome = (ModeloHome)ctx.lookup("ig.metrica.Modelo");
//        }
//        Collection resultado = modeloHome.findByAll();
//        Collection lista = new ArrayList();
//        Iterator i = resultado.iterator();
//        while (i.hasNext()){
//            Modelo modelo = (Modelo)i.next();
//            lista.add( new String( modelo.getNombre()));
//        }
//        return lista;
//    }
//    public Collection getModelos() throws NamingException, RemoteException, FinderException{
//        ctx = new InitialContext(prop);
//
//        if(modeloHome==null){
//            modeloHome = (ModeloHome)ctx.lookup("ig.metrica.Modelo");
//        }
//        Collection lista = new ArrayList();
//
//        Collection resultado = modeloHome.findByAll();
//        Iterator i = resultado.iterator();
//        while (i.hasNext()){
//            try {
//                Modelo modelo = (Modelo)i.next();
//                lista.add(modelo);
//            } catch (Exception e) {
//                log.info("No se pudo cargar un modelo:"+e.getMessage());
//                System.out.println("No se pudo cargar un modelo:"+e.getMessage());
//            }
//        }
//        return lista;
//    }
    
    private OrigenDeDatosHome origenDeDatosHome = null;
    public boolean EjecutarQuery(String query,String Data) throws NamingException, RemoteException, FinderException {
        if(origenDeDatosHome==null){
            ctx = new InitialContext(prop);
            origenDeDatosHome = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
        }
        OrigenDeDatos od = origenDeDatosHome.findByNombreEntidad( new String("ACCIONES") );
        boolean res = false;
        try {
            res=od.ejecutarQuery(query,Data);
        } catch (Exception e) {
        }
        return res;
    }
//    public int getPkModelo(String nombre) throws NamingException, RemoteException, FinderException {
//        if(modeloHome==null){
//            modeloHome = (ModeloHome)ctx.lookup("ig.metrica.Modelo");
//        }
////		ctx = new InitialContext(prop);
////		ModeloHome home2 = (ModeloHome)ctx.lookup("ig.metrica.Modelo");
//
//        ModeloPK pk = new ModeloPK(nombre);
//        Modelo modelo = modeloHome.findByPrimaryKey(pk);
//        int Id=(int)modelo.getIdModelo(nombre);
//        return Id;
//    }
    private Hashtable<String,OrigenDeDatos> PoolOrigenesDatos= new Hashtable<String,OrigenDeDatos>();
    
    public OrigenDeDatos getOrigenDatos(String entidad, boolean _b) {
        try {
            if(origenDeDatosHome==null){
                ctx = new InitialContext(prop);
                origenDeDatosHome = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
            }
            return origenDeDatosHome.findByNombreEntidad( entidad );
        } catch (RemoteException ex) {
            ex.printStackTrace();
        } catch (FinderException ex) {
            ex.printStackTrace();
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
        return null;
    }
    
    public OrigenDeDatos getOrigenDatos(String entidad) throws NamingException, RemoteException, FinderException{
        try {
            OrigenDeDatos origen =PoolOrigenesDatos.get(entidad.trim());
            if(origen==null){
                if(origenDeDatosHome==null){
                    ctx = new InitialContext(prop);
                    origenDeDatosHome = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
                }
                origen = origenDeDatosHome.findByNombreEntidad( entidad );
                
//                Collection ccc=origen.findByAllDTO();
                
                PoolOrigenesDatos.put(entidad,origen);
            }
            return origen;
        } catch (Exception e) {
            throw new NamingException(e.toString());
        }
    }
    
    public Collection<OrigenesdatosDTO> getAllOrigenDatosDTO() throws NamingException, RemoteException, FinderException{
        Collection<OrigenesdatosDTO> cReturn= new ArrayList<OrigenesdatosDTO>();
        try {
            OrigenDeDatos origen =null;
            if(origen==null){
                if(origenDeDatosHome==null){
                    ctx = new InitialContext(prop);
                    origenDeDatosHome = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
                }
                Collection ccc= origenDeDatosHome.findByAll();
                for (Object elem : ccc) {
                    cReturn.add(new OrigenesdatosDTO(
                            ((OrigenDeDatos)elem).getId(),
                            ((OrigenDeDatos)elem).getEntidad(),
                            ((OrigenDeDatos)elem).getCampos(),
                            ((OrigenDeDatos)elem).getQuery(),
                            ((OrigenDeDatos)elem).getConsecutivo()
                            ));
                }
//                    Collection ccc=origen.findByAllDTO();
                
//                    PoolOrigenesDatos.put(entidad,origen);
            }
            return cReturn;
        } catch (Exception e) {
            throw new NamingException(e.toString());
        }
    }
    
    public Collection getTodosOrigenDatos() throws NamingException, RemoteException, FinderException{
        if(origenDeDatosHome==null){
            ctx = new InitialContext(prop);
            origenDeDatosHome = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
        }
        
//		ctx = new InitialContext(prop);
//		OrigenDeDatosHome home = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
        Collection Todos=new ArrayList();
        try {
            Todos = origenDeDatosHome.findByAll();
        } catch (Exception e) {
        }
        return Todos;
    }
    
    public Collection getResultadoQuery(String Query,int pk) throws NamingException, RemoteException, FinderException {
        if(origenDeDatosHome==null){
            ctx = new InitialContext(prop);
            origenDeDatosHome = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
        }
//                ctx = new InitialContext(prop);
        OrigenDeDatosPK mPk = new OrigenDeDatosPK(pk);
//		OrigenDeDatosHome home = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
        OrigenDeDatos origenDeDatos= origenDeDatosHome.findByPrimaryKey(mPk);
        Collection result = new ArrayList();
        try {
            result = origenDeDatos.obtenerResultado(Query);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return result;
    }
    public InitialContext getContexto() throws NamingException{
        ctx = new InitialContext(prop);
        return ctx;
    }
    
    private Object lookup(String jndiName) throws NamingException {
        return ctx.lookup(jndiName);
    }
    
    /**
     * will get the ejb Local home factory.
     * clients need to cast to the type of EJBHome they desire
     *
     * @return the Local EJB Home corresponding to the homeName
     */
    public EJBLocalHome getLocalHome(String jndiHomeName) throws NamingException {
        return (EJBLocalHome) lookup(jndiHomeName);
    }
    
    /**
     * will get the ejb Remote home factory.
     * clients need to cast to the type of EJBHome they desire
     *
     * @return the EJB Home corresponding to the homeName
     */
    public EJBHome getRemoteHome(String jndiHomeName, Class className) throws NamingException {
        Object objref = lookup(jndiHomeName);
        return (EJBHome) PortableRemoteObject.narrow(objref, className);
    }
    
    /**
     * This method helps in obtaining the jms connection factory
     * @return the factory for obtaining jms connection
     */
    public ConnectionFactory getConnectionFactory(String connFactoryName) throws NamingException {
        return (ConnectionFactory) lookup(connFactoryName);
    }
    
    /**
     * This method obtains the topc itself for a caller
     * @return the Topic Destination to send messages to
     */
    public Destination getDestination(String destName) throws NamingException {
        return (Destination) lookup(destName);
    }
    
    /**
     * This method obtains the datasource itself for a caller
     * @return the DataSource corresponding to the name parameter
     */
    public DataSource getDataSource(String dataSourceName) throws NamingException {
        return (DataSource) lookup(dataSourceName);
    }
    
//    /**
//     * This method obtains the E-mail session itself for a caller
//     * @return the Session corresponding to the name parameter
//     */
//    public Session getSession(String sessionName) throws NamingException {
//        return (Session) lookup(sessionName);
//    }
    
    /**
     * @return the URL value corresponding
     * to the env entry name.
     */
    public URL getUrl(String envName) throws NamingException {
        return (URL) lookup(envName);
    }
    
    /**
     * @return the boolean value corresponding
     * to the env entry
     */
    public boolean getBoolean(String envName) throws NamingException {
        Boolean bool = (Boolean) lookup(envName);
        return bool.booleanValue();
    }
    
    /**
     * @return the String value corresponding
     * to the env entry name.
     */
    public String getString(String envName) throws NamingException {
        return (String) lookup(envName);
    }
//    private MatrizCorrelacionHome home =null;
//    public Collection findMatrizCorrelacion() {
//        try {
//            if(home==null){
//                ctx = new InitialContext(prop);
//                home = (MatrizCorrelacionHome)ctx.lookup("ig.metrica.riesgo.MatrizCorrelacion");
//            }
//            return home.findByPropiedades("", null, null, "");
//        } catch (RemoteException ex) {
//            ex.printStackTrace();
//        } catch (FinderException ex) {
//            ex.printStackTrace();
//        } catch (NamingException ex) {
//            ex.printStackTrace();
//        }
//        return null;
//    }
//    public MatrizCorrelacion findMatrizCorrelacionById(Integer id) {
//        try {
//            if(home==null){
//                ctx = new InitialContext(prop);
//                home = (MatrizCorrelacionHome)ctx.lookup("ig.metrica.riesgo.MatrizCorrelacion");
//            }
//            return home.findById(id);
//        } catch (RemoteException ex) {
//            ex.printStackTrace();
//        } catch (FinderException ex) {
//            ex.printStackTrace();
//        } catch (NamingException ex) {
//            ex.printStackTrace();
//        }
//        return null;
//    }
//    public Modelo getModelo(ModeloPK modeloPK) {
//        try {
//            if(modeloHome==null)
//                modeloHome = (ModeloHome)ctx.lookup("ig.metrica.Modelo");
//            return modeloHome.findByPrimaryKey(modeloPK);
//        } catch (RemoteException ex) {
//            ex.printStackTrace();
//        } catch (FinderException ex) {
//            ex.printStackTrace();
//        } catch (NamingException ex) {
//            ex.printStackTrace();
//        }
//        return null;
//    }
}
